package main

import (
	"fmt"
	"net"
	"net/http"
	"os"
	"strconv"
	"strings"
	"syscall"

	"sieve_engine/lib/config"
	"sieve_engine/lib/log"
	"sieve_engine/manager"

	"github.com/gin-contrib/pprof"
	"github.com/gin-gonic/gin"
)

var (
	managerController = manager.NewManagerController()
	host              = *config.String("web.host", "0.0.0.0:9610", "web host")
	runMode           = *config.String("web.run_mode", "debug", "web run mode")
)

func isAddressInUse(err error) bool {
	if opErr, ok := err.(*net.OpError); ok {
		if sysErr, ok := opErr.Err.(*os.SyscallError); ok {
			if no, ok := sysErr.Err.(syscall.Errno); ok {
				/*
					windows.WSAEADDRINUSE = 10048
				*/
				if no == syscall.EADDRINUSE || no == 10048 {
					return true
				}
			}
		}
	}
	return false
}

func NewWebServer() error {

	gin.SetMode(runMode)

	router := gin.New()
	router.Use(gin.Recovery())

	/*
		设置内存大小限制为10MB
		允许的最大内容长度(256MB = 256 << 20)
		允许的最大内容长度(32MB  = 32 << 20)
	*/
	router.MaxMultipartMemory = 32 << 20 //
	api := router.Group("/api")
	pprof.RouteRegister(api)

	api.GET("task", managerController.GetTaskList)
	api.POST("task", managerController.Create)
	api.GET("task.detail", managerController.GetTaskDetail)
	api.POST("task.control", managerController.Control)
	api.POST("task.settings", managerController.Settings)
	api.GET("task.result", managerController.GetTaskResult)

	api.GET("cluster", managerController.GetClusterList)

	log.Info(fmt.Sprintf("开启WEB 服务，监听地址: %s", host))
	var (
		maxAttempts = 100
		ss          = strings.Split(host, ":")
		ip          = ss[0]
		port, _     = strconv.Atoi(ss[1])
	)

try:
	httpServer := &http.Server{
		Addr:    fmt.Sprintf("%v:%v", ip, port),
		Handler: router,
	}

	if err := httpServer.ListenAndServe(); err != nil {
		fmt.Println(err)
		if b := isAddressInUse(err); b {
			port = (port + 1) % 65535
			if maxAttempts > 0 {
				maxAttempts = maxAttempts - 1
				goto try
			} else {
				return err
			}
		}
	}

	return nil
}
